package com.raidpoints.client;

import java.util.ArrayList;
import java.util.HashMap;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

public class GroupList extends Composite{
	DockLayoutPanel dpan;
	HorizontalPanel ppan;
	RaidPoints rp;
	CellTable<String> gTable;
	ListDataProvider<String> dataProvider;
	SingleSelectionModel<String> selectionModel;
	SimplePager simplePager;
	Button lootButton;
	
	GroupList(RaidPoints mrp){
		rp = mrp;
		
		dpan = new DockLayoutPanel(Unit.EM);
		ppan = new HorizontalPanel(); ppan.setSpacing(2);
		ScrollPanel span = new ScrollPanel();
		initWidget(dpan);
		
		dataProvider = new ListDataProvider<String>();
		selectionModel = new SingleSelectionModel<String>();
		gTable = new CellTable<String>();
		gTable.setSize("100%", "100%");
		gTable.setPageSize(50);
		gTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		dataProvider.addDataDisplay(gTable);
		gTable.setSelectionModel(selectionModel);
		SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
		simplePager = new SimplePager(TextLocation.CENTER,pagerResources,false,0,true);
		simplePager.setDisplay(gTable);
		
		ppan.add(simplePager); ppan.add(new Label("Click group to see info"));
		if(rp.auth == RaidPoints.AuthType.admin){
			lootButton = new Button("Loot Editor");
			lootButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					LootEditor le = new LootEditor(rp);
					le.center(); le.show();
				}
			});
			ppan.add(lootButton);
		}
		dpan.addNorth(ppan, 3);
		span.add(gTable);

		TextColumn<String> nameCol = new TextColumn<String>(){
			@Override
			public String getValue(String object) {
				return object.split(":;:")[1];
			}
		};
		gTable.addColumn(nameCol,"Group Name");
		
		
		TextColumn<String> nattCol = new TextColumn<String>(){
			@Override
			public String getValue(String object) {
				return object.split(":;:")[2];
			}
		};
		gTable.addColumn(nattCol,"Events Created By Group");
		
		dpan.add(span);
		
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler(){
			public void onSelectionChange(SelectionChangeEvent event) {
				String selected = selectionModel.getSelectedObject();
				if(selected != null){
					GroupInfoBox gib = new GroupInfoBox(Integer.parseInt(selected.split(":;:")[0]),rp);
					gib.center(); gib.show();
					selectionModel.setSelected(selected,false);
				}	
				
			}	
		});
		
		AsyncCallback<ArrayList<String>> groupCallback = new AsyncCallback<ArrayList<String>>(){

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(ArrayList<String> result) {
				if(result == null) return;
				dataProvider.getList().clear();
				dataProvider.getList().addAll(result);
				
				gTable.setRowCount(result.size());
				simplePager.firstPage();
			}
			
		};
		
		rp.rpsvc.GetGroups(groupCallback);		
		
	}
	
	
	public static class GroupInfoBox extends DialogBox{
		int gid;
		String name;
		RaidPoints rp;
		Button closeButton;
		Button saveButton;
		Button peButton;
		Button poolButton;
		TextArea descArea;
		
		GroupInfoBox(int mgid, RaidPoints mrp){
			rp = mrp;
			VerticalPanel vpan = new VerticalPanel();
			setHTML("Group Info");
			vpan.setSize("500px","500px");
			setWidget(vpan);
			
			gid = mgid;
			name = "";
			
			descArea = new TextArea();
			descArea.setSize("500px", "450px");
			descArea.setReadOnly(true);
			vpan.add(descArea);
			HorizontalPanel bpan = new HorizontalPanel();
			bpan.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
			bpan.setSpacing(5);
			vpan.add(bpan);
			closeButton = new Button("Close");
			saveButton = new Button("Save");
			saveButton.setVisible(false);
			peButton = new Button("Ruleset Editor");
			peButton.setVisible(false);
			poolButton = new Button("Pool Access");
			if(rp.auth != RaidPoints.AuthType.admin) poolButton.setVisible(false);
			bpan.add(saveButton); bpan.add(peButton); bpan.add(poolButton); bpan.add(closeButton);
			
			closeButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					hide();					
				}
			});
			
			saveButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					rp.rpsvc.SaveGroupDesc(descArea.getText(), gid, rp.stringCallback);
					hide();					
				}
			});
			
			peButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					PointsEditor pe = new PointsEditor(rp);
					pe.center(); pe.show(); hide();
				}
			});
			
			poolButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					GroupPoolAssignBox gpab = new GroupPoolAssignBox(gid,rp);
					gpab.center(); gpab.show(); hide();
				}
			});
			
			AsyncCallback<String> descCallback = new AsyncCallback<String>(){

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(String result) {
					if(result == null) return;
					String[] split = result.split(":;:");
					if(split[0].equals("1")){
						saveButton.setVisible(true);
						peButton.setVisible(true);
						descArea.setReadOnly(false);
					}
					setHTML(split[1] + " Info");
					if(split.length > 2) descArea.setText(split[2]);
				}
				
			};
			
			rp.rpsvc.GetGroupDesc(gid, descCallback);
		}
		
	}
	
	public static class GroupPoolAssignBox extends DialogBox{
		int gid; 
		VerticalPanel vpan;
		ListBox poolList;
		ArrayList<Integer> idList;
		RaidPoints rp;
		
		GroupPoolAssignBox(int mgid, RaidPoints mrp){
			gid = mgid; 
			rp = mrp;
			setHTML("Points Pool Assignment");
			vpan = new VerticalPanel();
			setWidget(vpan);
			poolList = new ListBox(true);
			poolList.setVisibleItemCount(7);
			poolList.setHeight("200px");
			vpan.add(poolList);
			idList = new ArrayList<Integer>();
			
			AsyncCallback<ArrayList<String>> poolCallback = new AsyncCallback<ArrayList<String>>(){
				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(ArrayList<String> result) {
					for(String s : result){
						String ts = s;
						boolean sel = ts.startsWith(":;:");
						if(sel) ts = ts.substring(3);
						idList.add(Integer.parseInt(ts.split(":;:")[0]));
						poolList.addItem(ts.split(":;:")[1]);
						poolList.setItemSelected(poolList.getItemCount()-1, sel);
					}
				}
			};
			rp.rpsvc.GetAllPools(gid, true, poolCallback);
			
			Button newButton = new Button("New Pool");
			vpan.add(newButton);
			
			HorizontalPanel buttonPan = new HorizontalPanel();
			vpan.add(buttonPan);
			Button saveButton = new Button("Save");
			Button closeButton = new Button("Close");
			buttonPan.add(saveButton); buttonPan.add(closeButton);
			
			newButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					NewPoolBox npb = new NewPoolBox();
					npb.center(); npb.show();
				}
			});
			
			saveButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					ArrayList<Integer> selId = new ArrayList<Integer>();
					for(int i = 0; i < poolList.getItemCount(); i++){
						if(poolList.isItemSelected(i)) selId.add(idList.get(i));
					}
					rp.rpsvc.SetGroupPools(gid, selId, rp.stringCallback);
					hide();
				}
			});
			
			closeButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					hide();					
				}
			});
		}
		
		public class NewPoolBox extends DialogBox{
			VerticalPanel vpan;
			TextBox nameBox;
			ListBox gameBox;
			ArrayList<gameinfo> games;
			CheckBox rulesetBox;
			
			NewPoolBox(){
				setHTML("New Points Pool");
				vpan = new VerticalPanel();
				setWidget(vpan);
				nameBox = new TextBox();
				gameBox = new ListBox();
				rulesetBox = new CheckBox("Has Ruleset");
				rulesetBox.setValue(true);
				games = new ArrayList<gameinfo>();
				vpan.add(nameBox); vpan.add(gameBox); vpan.add(rulesetBox);
				
				AsyncCallback<ArrayList<gameinfo>> gameCallback = new AsyncCallback<ArrayList<gameinfo>>(){
					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void onSuccess(ArrayList<gameinfo> result) {
						games.addAll(result);
						for(gameinfo gi : games) gameBox.addItem(gi.game);
					}
				};
				rp.rpsvc.GetGames(gameCallback);
				
				HorizontalPanel buttonPan = new HorizontalPanel();
				vpan.add(buttonPan);
				Button closeButton = new Button("Close");
				Button addButton = new Button("Add");
				buttonPan.add(addButton); buttonPan.add(closeButton);
				
				addButton.addClickHandler(new ClickHandler(){
					@Override
					public void onClick(ClickEvent event) {
						if(nameBox.getText().equals("")){
							Window.alert("Must enter pool name");
							return;
						}
						final String pname = nameBox.getText();
						AsyncCallback<Integer> newPoolCallback = new AsyncCallback<Integer>(){
							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub
								
							}

							@Override
							public void onSuccess(Integer result) {
								if(result == null){
									Window.alert("Pool already exists");
									return;
								}
								poolList.addItem(pname);
								idList.add(result);
							}
						};
						rp.rpsvc.AddNewPool(games.get(gameBox.getSelectedIndex()).ngsid, pname, rulesetBox.getValue(), newPoolCallback);
						hide();
					}
				});
				
				closeButton.addClickHandler(new ClickHandler(){
					@Override
					public void onClick(ClickEvent event) {
						hide();					
					}
				});
				
				
			}
		}
	}
}
